﻿/*
Adapted from AAPlus library by PJ Naughter
Permission was granted to convert the library to C#

This source is modified from PJ Naugters AA+ lib
(http://www.naughter.com/aa.html)
and therefore is covered under his copyright license, which
is as follows:

Purpose: Implementation for the algorithms for the Moon's Elongation, Phase Angle and Illuminated Fraction
Created: PJN / 29-12-2003
History: PJN / 26-01-2007 1. Changed name of IluminatedFraction to 
                          IlluminatedFraction. Thanks to Ing. Taras Kapuszczak
                          for reporting this typo!.

Copyright (c) 2003 - 2009 by PJ Naughter (Web: www.naughter.com, Email: pjna@naughter.com)

All rights reserved.

Copyright / Usage Details:

You are allowed to include the source code in any product (commercial, shareware, freeware or otherwise) 
when your product is released in binary form. You are allowed to modify the source code in any way you want 
except you cannot modify the copyright details at the top of each module. If you want to distribute source 
code with your application, then you are only allowed to distribute versions released by the author. This is 
to maintain a single distribution point for the source code. 

*/


using System;

namespace AAPlus
{
    public static class MoonIlluminatedFraction
    {

        public static double GeocentricElongation(double ObjectAlpha, double ObjectDelta, double SunAlpha, double SunDelta)
        {
            //Convert the RA's to radians
            ObjectAlpha = CoordinateTransformation.DegreesToRadians(ObjectAlpha * 15);
            SunAlpha = CoordinateTransformation.DegreesToRadians(SunAlpha * 15);

            //Convert the declinations to radians
            ObjectDelta = CoordinateTransformation.DegreesToRadians(ObjectDelta);
            SunDelta = CoordinateTransformation.DegreesToRadians(SunDelta);

            //Return the result
            return CoordinateTransformation.RadiansToDegrees(Math.Acos(Math.Sin(SunDelta) * Math.Sin(ObjectDelta) + Math.Cos(SunDelta) * Math.Cos(ObjectDelta) * Math.Cos(SunAlpha - ObjectAlpha)));
        }

        public static double PhaseAngle(double GeocentricElongation, double EarthObjectDistance, double EarthSunDistance)
        {
            //Convert from degrees to radians
            GeocentricElongation = CoordinateTransformation.DegreesToRadians(GeocentricElongation);

            //Return the result
            return CoordinateTransformation.MapTo0To360Range(CoordinateTransformation.RadiansToDegrees(Math.Atan2(EarthSunDistance * Math.Sin(GeocentricElongation), EarthObjectDistance - EarthSunDistance * Math.Cos(GeocentricElongation))));
        }

        public static double IlluminatedFraction(double PhaseAngle)
        {
            //Convert from degrees to radians
            PhaseAngle = CoordinateTransformation.DegreesToRadians(PhaseAngle);

            //Return the result
            return (1 + Math.Cos(PhaseAngle)) / 2;
        }

        public static double PositionAngle(double Alpha0, double Delta0, double Alpha, double Delta)
        {
            //Convert to radians
            Alpha0 = CoordinateTransformation.HoursToRadians(Alpha0);
            Alpha = CoordinateTransformation.HoursToRadians(Alpha);
            Delta0 = CoordinateTransformation.DegreesToRadians(Delta0);
            Delta = CoordinateTransformation.DegreesToRadians(Delta);

            return CoordinateTransformation.MapTo0To360Range(CoordinateTransformation.RadiansToDegrees(Math.Atan2(Math.Cos(Delta0) * Math.Sin(Alpha0 - Alpha), Math.Sin(Delta0) * Math.Cos(Delta) - Math.Cos(Delta0) * Math.Sin(Delta) * Math.Cos(Alpha0 - Alpha))));
        }

    }
}
